﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ITAP.ShprossesBuilder.Modelling.Components;
using ITAP.Core.Modelling.Primitives;
using ITAP.ShprossesBuilder.Properties;

namespace ITAP.ShprossesBuilder.Operations
{
    public class OperationBreakCrossConnection : IOperation
    {
        #region IOperation Members

        public string Name
        {
            get { return "Разбить пересекающиеся профили"; }
        }

        public OperationGroup OperationGroup
        {
            get { return OperationGroup.ShprossOperation; }
        }

        public System.Drawing.Image Thumbnail
        {
            get { return Resources.BreakCrossShprosses.ToBitmap(); }
        }

        public void Execute(ModelControl modelControl)
        {
            List<IComponent> shprosses = modelControl.ModelContainer.SelectedComponentsStack.GetComponentsByType(typeof(Shpross));
            if (shprosses.Count < 2)
                return;
            Shpross mainShpross = shprosses[0] as Shpross;
            Shpross auxiliaryShpross = shprosses[1] as Shpross;
            List<IComponent> crossConnectors = mainShpross.ConnectedComponents.GetComponentsByType(typeof(CrossConnector));
            if (crossConnectors.Count == 0)
                return;

            List<CrossConnector> connectedCrossConnectors = new List<CrossConnector>();
            foreach (CrossConnector connector in crossConnectors)
            {
                if (auxiliaryShpross.IsConnected(connector))
                    connectedCrossConnectors.Add(connector);
            }
            foreach (CrossConnector connector in connectedCrossConnectors)
            {
                IEndedPrimitive[] newPrimitives =
                    ((IEndedPrimitive)auxiliaryShpross.Primitives[0]).BreakInPoint(connector.Position, mainShpross.Width);

                List<IComponent> newShprosses = new List<IComponent>();
                for (int i = 0; i < newPrimitives.Length; i++)
                {
                    SpacerConnector startSpacerConnector = null;
                    if (auxiliaryShpross.StartSpacerConnector != null)
                        startSpacerConnector = auxiliaryShpross.StartSpacerConnector;

                    SpacerConnector endSpacerConnector = null;
                    if (auxiliaryShpross.EndSpacerConnector != null)
                        endSpacerConnector = auxiliaryShpross.EndSpacerConnector;

                    IWidePrimitive primitive = (IWidePrimitive)newPrimitives[i];

                    SpacerConnector start = null;
                    SpacerConnector end = null;
                    if(startSpacerConnector != null)
                        start = startSpacerConnector.CloneWithoutConnections();
                    if(endSpacerConnector != null)
                        end = endSpacerConnector.CloneWithoutConnections();

                    Shpross newShpross = ComponentFactory.CreateShprossWithSpacerConnectors(primitive.Width,
                            primitive.Height,
                            primitive.StartPoint,
                            primitive.EndPoint,
                            start,
                            end,
                            auxiliaryShpross.Article + " Clone #" + i.ToString(),
                            auxiliaryShpross.Color, auxiliaryShpross.BorderColor, auxiliaryShpross.UniqueId, auxiliaryShpross.AcceptedUniqueIdsToConnect.ToArray());
                    newShprosses.Add(newShpross);
                }

                IComponent shprossParent = auxiliaryShpross.Parent;
                if (shprossParent != null)
                {
                    shprossParent.RemoveInnerComponent(connector);
                    // При удалении внутреннего элемента удаляются и все коннекты элемента с другими элементами.
                    shprossParent.RemoveInnerComponent(auxiliaryShpross);
                    // Если есть предок, то надо в него добавить вновь созданные элементы.
                    foreach (IComponent newShpross in newShprosses)
                        shprossParent.AddInnerComponent(newShpross);
                }
                else
                    throw new Exception("У профиля, который разбивается, должен существовать предок!");
                break;
            }

        }

        public bool CanUndo
        {
            get { return true; }
        }

        #endregion
    }
}
